package com.yfbao.horizon.v8;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

public class OrgLogAnalysis {

    public static void main(String[] args) {
        if(args !=null && args.length>0){
            for (String arg : args) {
                System.out.println(arg);
                orgLog(arg);
            }
            return;
        }
        orgLog(null);
    }

    private static void orgLog(String path){
        String file ="C:\\Users\\byf78\\Desktop\\日志分析\\test\\organization-info.log";
        if(path!=null){
            file = path;
        }
        List<String> fifterList = getFifterList(file, "seeyon-dubbo-provider-");
        List<LogDto> logDtos = splitOrgLog(fifterList);
        File strFile = new File(file);
        String path1 = strFile.getParent();
        System.out.println(path1);
        analysisDubboLog(logDtos,path1);
    }

    private static void analysisDubboLog(List<LogDto> list,String outPath){
        Map<String,List<LogDto>> map = new HashMap<>();
        for (LogDto logDto : list) {
            if(!logDto.getThreadName().contains("seeyon-dubbo-provider-")){
                continue;
            }
            String threadName = logDto.getThreadName();
            List<LogDto> logDtos = map.get(threadName);
            if(logDtos ==null){
                logDtos = new ArrayList<>();
            }
            logDtos.add(logDto);
            map.put(threadName,logDtos);
        }

        String dubboEndStr="Dubbo调用耗时=";
        Set<String> set = map.keySet();
        Set<String> warnSet = new HashSet<>();
        List<String> warnList = new ArrayList<>();
        for (String key : set) {
            List<LogDto> logDtos = map.get(key);
            LogDto logDtoStart = null;
            int add =0;
            for (LogDto logDto : logDtos) {
                if(logDtoStart ==null ){
                    if(logDto.getLogInfo().contains(dubboEndStr)){
                        continue;
                    }
                    logDtoStart =logDto;
                    continue;
                }
                long time = logDto.getLogTime().getTime();
                long startTime = logDtoStart.getLogTime().getTime();
                if((time-startTime)>(60*1000) && !warnSet.contains(logDtoStart.getLogInfo())){
                    warnList.add(logDtoStart.getLogInfo());
                    warnSet.add(logDtoStart.getLogInfo());
                    add++;
                }
                if(logDto.getLogInfo().contains(dubboEndStr)){
                    logDtoStart = null;
                }
            }
            if(logDtoStart!=null && !warnSet.contains(logDtoStart.getLogInfo())){
                warnList.add(logDtoStart.getLogInfo());
                warnSet.add(logDtoStart.getLogInfo());
                add++;
            }
            if(add>0){
                warnList.add("  ");
                warnList.add(" ---------------------------------- ");
                warnList.add("  ");
            }
        }
        String outFile = outPath!=null ? outPath+File.separator+"warn.txt":"warn.txt";
        FileUtil.writeLines(warnList,outFile,"utf-8",true);
    }

    private static List<LogDto> splitOrgLog(List<String> logList){
        List<LogDto> list = new ArrayList<>();
        for (String str : logList) {
            String[] split = str.split(" ");
            int length = split.length;
            if(length<5){
                System.out.println("error log:"+str);
                continue;
            }
            DateTime dateTime = parseToDateTime(split[0], "yyyy-MM-dd");
            if(dateTime ==null){
                System.out.println("error parse logDate:"+str);
                continue;
            }

            DateTime dateTime2 = parseToDateTime(split[0]+" "+split[1], "yyyy-MM-dd HH:mm:ss,SSS");
            if(dateTime ==null){
                System.out.println("error parse logTime:"+str);
                continue;
            }
            LogDto logDto = new LogDto();
            logDto.setLogDate(dateTime);
            logDto.setLogTime(dateTime2);
            logDto.setLogInfo(split[2]);
            logDto.setThreadName(split[3]);
            if(split[3].trim().equals("")){
                logDto.setThreadName(split[4]);
            }
            logDto.setLogInfo(str);
            list.add(logDto);
        }
        return list;
    }


    private static List<String> getFifterList(String file, String... fifters){
        List<String> list = FileUtil.readLines(new File(file), "utf-8");
        List<String> collect = list.stream().filter(str -> {
            for (String fifter : fifters) {
                if (str.contains(fifter)) {
                    return true;
                }
            }
            return false;
        }).collect(Collectors.toList());
        return collect;
    }


    private static DateTime parseToDateTime(String str,String  format){
        try {
           return DateUtil.parse(str, format);
        }catch (Throwable t){
            System.out.println("parse datetime error, "+str);
        }
        return null;
    }


}
